package com.welike.shibo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.welike.shibo.eneity.JsonResult;
import com.welike.shibo.eneity.LoginUser;
import com.welike.shibo.eneity.User;
import com.welike.shibo.enums.ResultEnum;
import com.welike.shibo.mapper.FansMapper;
import com.welike.shibo.mapper.UserMapper;
import com.welike.shibo.mapper.VideoMapper;
import com.welike.shibo.service.RedisService;
import com.welike.shibo.service.UserService;
import com.welike.shibo.utils.*;
import com.welike.shibo.vo.UserInfoListVO;
import com.welike.shibo.vo.UserInfoVO;
import com.welike.shibo.vo.page.SearchUserPageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.List;

/**
 *
 * @author fangyu
 * @date 2019-08-20
 */

@Slf4j
@Service(value = "userServiceImpl")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Autowired
    private QiNiuUtil qiNiuUtil;

    @Autowired
    private FansMapper fansMapper;

    @Autowired
    private VideoMapper videoMapper;


    @Resource
    private RedisService redisService;

    @Value("${redis.key.reset}")
    private String REDIS_KEY_RESET;


    /**
     * 注册逻辑封装
     * @param phone 手机号
     * @param password 密码
     * @return JsonResult
     */
    @Override
    public JsonResult resgiter(String phone, String password) {
        return null;
    }

    @Override
    public LoginUser queryUserInfoByPhoneAndPwd(String phone, String password) {
        return userMapper.queryAllByPhoneAndPasswordAndStatus(phone, password);
    }

    // 通过手机号查询用户是否存在，即是否已经注册
    @Override
    public LoginUser queryUserByPhone(String phone) {
        return userMapper.queryAllByPhone(phone);
    }

    /**
     * 通过手机号查询
     * @param phone
     * @return
     */
    @Override
    public boolean queryPhoneByPhone(String phone) {
        return userMapper.queryPhoneByPhone(phone);
    }

    /**
     * 通过uid更新设备信息
     * @param deviceId
     * @param deviceType
     * @param uid
     */
    @Override
    public void updateDeviceInfoByUid(String deviceId, String deviceType, String uid) {
        userMapper.updateDeviceInfoByUid(deviceId, deviceType, uid);
    }

    // 关注列表
    @Override
    public List<String> queryFollowList(String uid) {
        return fansMapper.queryUserIdByFanId(uid);
    }

    // 粉丝列表
    @Override
    public List<String> queryFansList(String uid) {
        return fansMapper.queryFanIdByUserId(uid);
    }

    /**
     * 通过手机号查询账号状态
     * @param phone 手机号
     * @return
     */
    @Override
    public Integer queryStatusByPhone(String phone) {
        return userMapper.queryStatusByPhone(phone);
    }

    /**
     * 通过uid查询用户信息
     * @param uid
     * @return
     */
    @Override
    public User queryUserByUid(String uid) {
        return userMapper.queryUserByUid(uid);
    }

    @Override
    public String queryNickNameByUid(String uid) {
        return userMapper.queryNickNameByUid(uid);
    }

    @Override
    public String queryAvatarByUid(String uid) {
        return userMapper.queryAvatarByUid(uid);
    }

    @Override
    public String queryDeviceIdByUid(String uid) {
        return userMapper.queryDeviceIdByUid(uid);
    }

    @Override
    public String queryDeviceTypeByUid(String uid) {
        return userMapper.queryDeviceTypeByUid(uid);
    }

    @Override
    public UserInfoVO queryUserInfo(String uid) {
        int videoCounts = videoMapper.countByUserId(uid);
        int followCounts = fansMapper.countByFanId(uid);
        int fansCounts = fansMapper.countByUserId(uid);
        // 获赞
        int getLikeCounts = videoMapper.sumForLikeCountsByUserId(uid);
        User user = userMapper.queryUserByUid(uid);
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);
        userInfoVO.setVideoCount(videoCounts);
        userInfoVO.setFollowCount(followCounts);
        userInfoVO.setFansCount(fansCounts);
        userInfoVO.setGetLikeCount(getLikeCounts);
        return userInfoVO;
    }

    @Override
    public Integer countByUser() {
        return userMapper.countByUser();
    }

    // 后台用户统计
    @Override
    public IPage<UserInfoListVO> queryAllUserInfo(Integer page, Integer pageSize, String key) {
        Page<UserInfoListVO> p = new Page<>(page, pageSize);
        return userMapper.queryAllUserInfo(p, key);
    }

    // 上传头像
    @Override
    public String uploadAvatar(MultipartFile avatar) throws IOException {
        try {
            String originalFilename = avatar.getOriginalFilename();
            assert originalFilename != null;
            String fileExtend = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
            log.info("File Type ==> {}", fileExtend);
            FileInputStream inputStream = (FileInputStream) avatar.getInputStream();
            //默认不指定key的情况下，以当前日期+时间戳作为文件名
            String key = Tools.getYearMonth() + System.currentTimeMillis() + fileExtend;
            log.info("img_name ==> {}", key);
            return qiNiuUtil.upload(inputStream, key);
        }catch (Exception e){
            e.printStackTrace();
            return "上传失败";
        }
    }

    @Override
    public List<String> queryAllVipUser() {
        return userMapper.queryAllVipUser();
    }

    @Override
    public IPage<SearchUserPageVo> searchUser(Integer page, Integer pageSize, String key) {
        Page<SearchUserPageVo> p = new Page<>(page, pageSize);
        return userMapper.searchUser(p, key);
    }

    @Override
    public boolean queryUid(String uid) {
        return userMapper.queryByUid(uid);
    }

    @Override
    public String queryUidByPhone(String phone) {
        return userMapper.queryUidByPhone(phone);
    }

    @Override
    public JsonResult updateUser(JSONObject requestJson) {
        CommonUtil.hasAllRequired(requestJson, "avatar, nickname, phone, birthday, gender, address, signature, gender, level");
        Object birth = requestJson.getString("birthday");
        if (!"-".equals(birth)){
            try {
                // 更新格式化生日
                requestJson.put("birthday", Tools.DateFormat(birth));
            } catch (ParseException e){
                requestJson.put("birthday", "-");
                log.error("日期格式转换失败");
            }
        }
        if (requestJson.getString("password") != null){
            log.info("password => {}", requestJson.getString("password"));
            String phone = requestJson.getString("phone");
            String pwd = requestJson.getString("password");
            if (pwd.length() < 6){
                return ResultUtils.error(ResultEnum.PASSWORD_TOO_SHORT);
            }
            String newPwd = null;
            try {
                newPwd = PasswordEncrypt.encodeByMd5(pwd);
            } catch (NoSuchAlgorithmException e) {
                log.error("密码加密失败! ==> {}", e.getMessage());
                return ResultUtils.error("密码修改失败!请联系超管!");
            }
            userMapper.updatePasswordByPhone(newPwd, phone);
        } else {
            log.info("password is null => 不做修改");
        }
        int result = userMapper.updateUser(requestJson);
        if (result == 1){
            return ResultUtils.success("更新成功!");
        } else {
            return ResultUtils.error("更新失败!");
        }
    }

    @Override
    public JsonResult updateStatus(JSONObject requestJson) {
        CommonUtil.hasAllRequired(requestJson, "uid, status");
        int result = userMapper.updateStatus(requestJson);
        if (result == 1){
            return ResultUtils.success("更新成功!");
        } else {
            return ResultUtils.error("更新失败!");
        }
    }

    @Override
    public JsonResult resetPwd(String phone, String pwd) {
        // 手机号非空校验
        if (StringUtils.isEmpty(phone)) {
            return ResultUtils.error(ResultEnum.PHONE_DONT_NOT_NULL);
        }
        // 手机号正则校验
        if (!Tools.isMobile(phone)) {
            return ResultUtils.error(ResultEnum.PHONE_ERROR);
        }
        // 手机号不存在报错
        if (!userMapper.queryPhoneByPhone(phone)){
            return ResultUtils.error(ResultEnum.PHONE_ERROR);
        }
        // 没有验证码直接拦截
        String checkCode = redisService.get(REDIS_KEY_RESET + phone);
        if (checkCode == null) {
            return ResultUtils.error(ResultEnum.CAPTCHA_ERROR.getCode(), "请先获取验证码");
        }
        String newPwd = null;
        try {
            newPwd = PasswordEncrypt.encodeByMd5(pwd);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return ResultUtils.error(ResultEnum.E_400);
        }
        int result = userMapper.updatePasswordByPhone(newPwd, phone);
        if (result == 1){
            return ResultUtils.success("重置成功!");
        }
        return ResultUtils.error("修改失败!");
    }

}
